package com.logictech.activity.system.util;

import java.io.PrintStream;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class SignatureUtil {
	private static final Logger LOG = LoggerFactory.getLogger(SignatureUtil.class);

	public static String sign(Map<String, String> paramMap, String key) {
		if (key == null) {
			throw new IllegalArgumentException("key不能为空");
		}
		String sign = createSign(paramMap, key);
		return sign;
	}

	private static String createSign(Map<String, String> paramMap, String key) {
		StringBuffer sb = new StringBuffer();
		SortedMap sort = new TreeMap(paramMap);
		Set es = sort.entrySet();
		Iterator it = es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String k = (String) entry.getKey();
			String v = (String) entry.getValue();
			if ((v != null) && (!"".equals(v)) && (!"null".equals(v)) && (!"sign".equals(k)) && (!"key".equals(k))) {
				sb.append(k + "=" + v + "&");
			}
		}
		sb.append("key=" + key);
		LOG.info("HMAC source:{}", new Object[] { sb.toString() });
		String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
		LOG.info("HMAC:{}", new Object[] { sign });
		return sign;
	}

	public static String checkAuth(Map<String, String> params, String key) {

		// Map<String, String> params = new HashMap<String, String>();
		// for (Map.Entry<String, String[]> entry : paramsMap.entrySet()) {
		// params.put(entry.getKey(), entry.getValue()[0]);
		// }
		// APP_SECRET = ConfigUtils.getSysConfig("sys.app.secret");
		

		params = paraFilter(params, "sign");

		String content = createLinkString(params) +"&key="+key;
		System.out.println(content);
		return MD5(content);
		
	}

	/**
	 * MD5加密
	 *
	 * @param sStr
	 * @return String
	 */
	private final static String MD5(String sStr) {
		String sReturnCode = "";
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(sStr.getBytes("UTF-8"));
			byte b[] = md.digest();
			int i;
			StringBuffer sb = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0) {
					i += 256;
				}
				if (i < 16) {
					sb.append("0");
				}
				sb.append(Integer.toHexString(i));
			}

			sReturnCode = sb.toString();
		} catch (Exception ex) {

		}
		return sReturnCode;
	}

	public static String createLinkString(Map<String, String> params) {

		List<String> keys = new ArrayList<String>(params.keySet());
		Collections.sort(keys);
		String preStr = "";
		for (int i = 0; i < keys.size(); i++) {
			String key = keys.get(i);
			String value = params.get(key);
			if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
				preStr = preStr + key + "=" + value;
			} else {
				preStr = preStr + key + "=" + value + "&";
			}
		}

		return preStr;
	}

	/**
	 * 除去Map中的空值和指定参数Key
	 *
	 * @param params
	 * @return 去掉空值与指定参数Key后的新Map
	 */
	public static Map<String, String> paraFilter(Map<String, String> params, String... filterKeys) {
		Map<String, String> result = new HashMap<String, String>();

		if (params == null || params.size() <= 0) {
			return result;
		}
		for (String key : params.keySet()) {
			String value = params.get(key);
			if (value == null || value.equals("") || ArrayUtils.contains(filterKeys, key)) {
				continue;
			}
			result.put(key, value);
		}

		return result;
	}

	public static boolean checkSign(Map<String, String> paramMap, String key, String sign) {
		if (key == null) {
			throw new IllegalArgumentException("key不能为空");
		}
		if (sign == null) {
			throw new IllegalArgumentException("需要验签的字符为空");
		}
		LOG.info("HMAC sign:{}", new Object[] { sign });
		return sign.equals(sign(paramMap, key));
	}

	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		@SuppressWarnings("rawtypes")
		Map paramMap = new HashMap();
		paramMap.put("openid", "o9SrbjpQbDU0lj0aSROQGgAS3Cwo");
		paramMap.put("actId", "402880ee513747290151378f1b5a0007");
		paramMap.put("jwid", "gh_f0f070498613");
		paramMap.put("subscribe", "1");
		paramMap.put("sign", "F2028EF0D4B8B30A8FF337FD467B0294");
		String sign = (String) paramMap.get("sign");
		String key = "4B6CAED6F7B1912";
		String localsign = sign(paramMap, key);
		System.out.println(localsign);
		System.out.println(checkSign(paramMap, key, sign));
		System.out.println(checkAuth(paramMap,key));
	}
}
